﻿using System;
using System.Collections;
using ProjectDanmaku.Scenario;
using ProjectDanmaku.Util;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;

namespace ProjectDanmaku.Avatar.Basic
{
    public abstract class AvatarBehavior : MonoBehaviour
    {
        [SerializeField] private int maxDeathCount = 20;
        [SerializeField] private float speed = 1f;
        
        private static readonly int Side = Animator.StringToHash("Sided");

        protected Animator _animator;
        private SpriteRenderer _spriteRenderer;

        protected virtual void Awake()
        {
            _animator = GetComponent<Animator>();
            _spriteRenderer = GetComponent<SpriteRenderer>();
        }

        protected virtual void Start()
        {
            DanmakuScenario.GameStatistics.PlayerJikiCount = maxDeathCount;
        }

        protected virtual void OnEnable()
        {
            DanmakuScenario.CurrentAvatarBehavior = this;
        }

        protected virtual void OnDisable()
        {
            if (DanmakuScenario.CurrentAvatarBehavior == this) 
                DanmakuScenario.CurrentAvatarBehavior = null;
        }

        public virtual void Movement(Vector2 rawMovement)
        {
            var pos = MathHelper.Vec3ToVec2(transform.position);
            var moveVec = rawMovement * speed * Time.deltaTime;

            CoordUtility.CameraClip(pos, ref moveVec);
            
            transform.Translate(moveVec);

            var side = rawMovement.x != 0;
            _animator.SetBool(Side, side);

            _spriteRenderer.flipX = rawMovement.x > 0;
        }

        public abstract void Fire();
        public abstract void OnHit();

        /// <summary>
        ///     CollideCircle = Vec3(x, y, radius)
        /// </summary>
        /// <returns></returns>
        public virtual Vector3 GetCollideCircle()
        {
            var pos = transform.position;
            return new Vector3(pos.x, pos.y, CoordUtility.PixelToUnit(3));
        }

        #if UNITY_EDITOR
        private void OnDrawGizmos()
        {
            var collider = GetCollideCircle();
            
            Gizmos.DrawSphere(new Vector3(collider.x, collider.y, 0.2f), collider.z);
        }
        #endif
        
        public virtual void OnEnterMonsterState() {}
        public virtual void OnLeaveMonsterState() {}

        protected IEnumerator RaisingBulletDeathZone(float x, float y, float radius, float duration)
        {
            Debug.Log("RaisingBulletDeathZone: Start");
            
            DanmakuScenario.BulletDeathZone.x = x; 
            DanmakuScenario.BulletDeathZone.y = y; 
                
            var radiusRaising = Mathf.Min(radius, radius / (duration / 0.04f));
            var curRadius = 0f;
            
            for (;;)
            {
                curRadius += radiusRaising;
                DanmakuScenario.BulletDeathZone.z = curRadius;
                
                if (curRadius >= radius)
                    break;
                
                yield return new WaitForSecondsRealtime(0.04f);
            }
        }

        protected void RecordPlayerDeath()
        {
            Debug.Log("RecordPlayerDeath");
            
            DanmakuScenario.GameStatistics.PlayerJikiCount = 
                Mathf.Max(0, DanmakuScenario.GameStatistics.PlayerJikiCount - 1);
            if (DanmakuScenario.GameStatistics.PlayerJikiCount == 0)
            {
                DanmakuScenario.GameStatistics.PlayerLose = true;
                SceneManager.LoadScene("Scenes/GameResults");
            }
        }
    }
}